﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;
using System.IO;

namespace AssemblyCYG
{
    public partial class MeaRingForm : Form
    {
        bool isPaintShape = false;
        HObject unionROI = null;
        HObject ho_Image = null;
        HTuple hv_ImageWidth = null;
        HTuple hv_ImageHeight = null;
        HTuple hv_Channel = null;
        double scaleS_X = 0;
        double scaleS_Y = 0;
        double scaleE_X = 0;
        double scaleE_Y = 0;
        int keyNum = 0;
        int wheelNum = 0;
        Point mouseDownPoint = new Point();
        System.Diagnostics.Stopwatch detectTime = new System.Diagnostics.Stopwatch();   //记录各工具的检测时间
        System.Diagnostics.Stopwatch mouseDownTime = new System.Diagnostics.Stopwatch();
        HalconAlgorithm halconAlgorithm = new HalconAlgorithm();
        HObject ho_fitCircleContour = null;
        HObject ho_AffinTransRegion = null;
        public FitCirclePara outFitCirclePara = new FitCirclePara();
        MatchPara curMatchPara = new MatchPara();
        string modelImageFold = Path.Combine(System.Environment.CurrentDirectory, "model", "upCamLocate");
        public MeaRingForm(FitCirclePara inFitCirclePara, string mImagePath, MatchPara inMatchPara)
        {
            InitializeComponent();
            InitialControls();
            modelImageFold = mImagePath;
            outFitCirclePara.minGray = inFitCirclePara.minGray;
            outFitCirclePara.maxGray = inFitCirclePara.maxGray;
            outFitCirclePara.contrast = inFitCirclePara.contrast;
            outFitCirclePara.fitNum = inFitCirclePara.fitNum;
            outFitCirclePara.sigma = inFitCirclePara.sigma;
            outFitCirclePara.limitMinRingWidth = inFitCirclePara.limitMinRingWidth;
            outFitCirclePara.limitMaxRingWidth = inFitCirclePara.limitMaxRingWidth;
            //outFitCirclePara.seekPointPath = inFitCirclePara.seekPointPath;
            outFitCirclePara.isInheritModel = inFitCirclePara.isInheritModel;
            if (inFitCirclePara.ho_ROI != null)
                outFitCirclePara.ho_ROI = inFitCirclePara.ho_ROI;
            LoadFitCirclePara();    //加载参数
            curMatchPara.modelLocationRow = inMatchPara.modelLocationRow;   //加载当前匹配参数
            curMatchPara.modelLocationCol = inMatchPara.modelLocationCol;
            curMatchPara.modelMatchType = inMatchPara.modelMatchType;
            curMatchPara.seekAngleStart = inMatchPara.seekAngleStart;
            curMatchPara.seekAngleRange = inMatchPara.seekAngleRange;
            curMatchPara.seekModelNum = inMatchPara.seekModelNum;
            curMatchPara.seekModelScore = inMatchPara.seekModelScore;
        }
        private void LoadFitCirclePara()
        {
            this.FitCircleMinGray.Value = outFitCirclePara.minGray;
            this.FitCircleMaxGray.Value = outFitCirclePara.maxGray;
            this.FitCircle_contrast.Value = outFitCirclePara.contrast;
            this.FitCircle_pnum.Value = outFitCirclePara.fitNum;
            this.FitCircle_sigma.Value = outFitCirclePara.sigma;
            this.tB_limitMinWidth.Text = outFitCirclePara.limitMinRingWidth.ToString();
            this.tB_limitMaxWidth.Text = outFitCirclePara.limitMaxRingWidth.ToString();
            //this.cB_FitCircle_seekPath.SelectedIndex = outFitCirclePara.seekPointPath;
            if (outFitCirclePara.isInheritModel)
                this.cB_inheritModel.Checked = true;
            else
                this.cB_inheritModel.Checked = false;
            if (outFitCirclePara.ho_ROI != null)
                unionROI = outFitCirclePara.ho_ROI.Clone();
        }
        private void InitialControls()
        {
            this.cB_RoiRelation.SelectedIndex = 0;
            //this.cB_FitCircle_seekPath.SelectedIndex = 0;
            HOperatorSet.SetDraw(hWindowControl1.HalconWindow, "margin");
            HOperatorSet.SetLineWidth(hWindowControl1.HalconWindow, 2);
        }
        #region 绘图及窗体鼠标操作事件
        private void btn_DrawRect_Click(object sender, EventArgs e)
        {
            hWindowControl1.Focus();
            HObject ho_Rectangle;
            HTuple hv_Row1 = null, hv_Column1 = null;
            HTuple hv_Row2 = null, hv_Column2 = null;
            HOperatorSet.GenEmptyObj(out ho_Rectangle);
            HOperatorSet.SetColor(hWindowControl1.HalconWindow, "blue");
            isPaintShape = true;
            this.tableLayoutPanel3.Enabled = false;
            HOperatorSet.DrawRectangle1(hWindowControl1.HalconWindow, out hv_Row1, out hv_Column1, out hv_Row2, out hv_Column2);
            this.tableLayoutPanel3.Enabled = true;
            isPaintShape = false;
            ho_Rectangle.Dispose();
            HOperatorSet.GenRectangle1(out ho_Rectangle, hv_Row1, hv_Column1, hv_Row2, hv_Column2);
            switch (this.cB_RoiRelation.SelectedIndex)
            {
                case 0:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Union2(ho_Rectangle, unionROI, out unionROI);
                    ShowDetectContour();
                    break;
                case 1:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Intersection(unionROI, ho_Rectangle, out unionROI);
                    ShowDetectContour();
                    break;
                case 2:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Difference(unionROI, ho_Rectangle, out unionROI);
                    ShowDetectContour();
                    break;
            }
            ho_Rectangle.Dispose();
        }
        private void btn_drawRoRect_Click(object sender, EventArgs e)
        {
            hWindowControl1.Focus();
            HObject ho_Rectangle;
            HTuple hv_Row = null, hv_Column = null;
            HTuple hv_Phi = null, hv_Length1 = null, hv_Length2 = null;
            HOperatorSet.GenEmptyObj(out ho_Rectangle);
            HOperatorSet.SetColor(hWindowControl1.HalconWindow, "blue");
            isPaintShape = true;
            this.tableLayoutPanel3.Enabled = false;
            HOperatorSet.DrawRectangle2(hWindowControl1.HalconWindow, out hv_Row, out hv_Column, out hv_Phi, out hv_Length1, out hv_Length2);
            this.tableLayoutPanel3.Enabled = true;
            isPaintShape = false;
            ho_Rectangle.Dispose();
            HOperatorSet.GenRectangle2(out ho_Rectangle, hv_Row, hv_Column, hv_Phi, hv_Length1, hv_Length2);
            switch (this.cB_RoiRelation.SelectedIndex)
            {
                case 0:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Union2(ho_Rectangle, unionROI, out unionROI);
                    ShowDetectContour();
                    break;
                case 1:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Intersection(unionROI, ho_Rectangle, out unionROI);
                    ShowDetectContour();
                    break;
                case 2:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Difference(unionROI, ho_Rectangle, out unionROI);
                    ShowDetectContour();
                    break;
            }
            ho_Rectangle.Dispose();
        }
        private void btn_drawCircle_Click(object sender, EventArgs e)
        {
            hWindowControl1.Focus();
            HTuple hv_Row = null, hv_Column = null, hv_Radius = null;
            HObject ho_Circle;
            HOperatorSet.GenEmptyObj(out ho_Circle);
            HOperatorSet.SetColor(hWindowControl1.HalconWindow, "blue");
            isPaintShape = true;
            this.tableLayoutPanel3.Enabled = false;
            HOperatorSet.DrawCircle(hWindowControl1.HalconWindow, out hv_Row, out hv_Column, out hv_Radius);
            this.tableLayoutPanel3.Enabled = true;
            isPaintShape = false;
            ho_Circle.Dispose();
            HOperatorSet.GenCircle(out ho_Circle, hv_Row, hv_Column, hv_Radius);
            switch (this.cB_RoiRelation.SelectedIndex)
            {
                case 0:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Union2(ho_Circle, unionROI, out unionROI);
                    ShowDetectContour();
                    break;
                case 1:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Intersection(unionROI, ho_Circle, out unionROI);
                    ShowDetectContour();
                    break;
                case 2:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Difference(unionROI, ho_Circle, out unionROI);
                    ShowDetectContour();
                    break;
            }
            ho_Circle.Dispose();
        }
        private void btn_drawPoly_Click(object sender, EventArgs e)
        {
            hWindowControl1.Focus();
            HObject ho_Region;
            HOperatorSet.GenEmptyObj(out ho_Region);
            HOperatorSet.SetColor(hWindowControl1.HalconWindow, "blue");
            isPaintShape = true;
            ho_Region.Dispose();
            this.tableLayoutPanel3.Enabled = false;
            HOperatorSet.DrawRegion(out ho_Region, hWindowControl1.HalconWindow);
            this.tableLayoutPanel3.Enabled = true;
            isPaintShape = false;
            switch (this.cB_RoiRelation.SelectedIndex)
            {
                case 0:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Union2(ho_Region, unionROI, out unionROI);
                    ShowDetectContour();
                    break;
                case 1:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Intersection(unionROI, ho_Region, out unionROI);
                    ShowDetectContour();
                    break;
                case 2:
                    if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                    HOperatorSet.Difference(unionROI, ho_Region, out unionROI);
                    ShowDetectContour();
                    break;
            }
            ho_Region.Dispose();
        }
        private void btn_clearROI_Click(object sender, EventArgs e)
        {
            if (ho_Image != null)
            {
                HOperatorSet.GenEmptyObj(out unionROI);
                HOperatorSet.GenEmptyObj(out ho_fitCircleContour);
                //HOperatorSet.GenEmptyObj(out ho_defectUnionContour);
                //HOperatorSet.GenEmptyObj(out AffineTransUnionRegion);
                unionROI = null;
                hWindowControl1.HalconWindow.ClearWindow();
                HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);
                hWindowControl1.Refresh();
            }
        }
        private void cB_RoiRelation_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
        private void ShowDetectContour()
        {
            hWindowControl1.HalconWindow.ClearWindow();
            if (ho_Image != null) HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);
            HOperatorSet.SetColor(hWindowControl1.HalconWindow, "blue");
            if (unionROI != null && unionROI.IsInitialized()) HOperatorSet.DispObj(unionROI, hWindowControl1.HalconWindow);
            //HOperatorSet.SetColor(hWindowControl1.HalconWindow, "red");
            //if (ho_defectUnionContour != null && this.cB_showDefectContour.Checked) HOperatorSet.DispObj(ho_defectUnionContour, hWindowControl1.HalconWindow);
            HOperatorSet.SetColor(hWindowControl1.HalconWindow, "red");
            if (ho_fitCircleContour != null) HOperatorSet.DispObj(ho_fitCircleContour, hWindowControl1.HalconWindow);
            HOperatorSet.SetColor(hWindowControl1.HalconWindow, "cyan");
            if (ho_AffinTransRegion != null) HOperatorSet.DispObj(ho_AffinTransRegion, hWindowControl1.HalconWindow);
            //ShowProductIndex();    //显示产品序列
            hWindowControl1.Refresh();
        }
        private void 清除检测线ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (ho_Image != null)
            {
                HOperatorSet.GenEmptyObj(out ho_fitCircleContour);
                HOperatorSet.GenEmptyObj(out ho_AffinTransRegion);
                hWindowControl1.HalconWindow.ClearWindow();
                HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);
                if (unionROI != null) HOperatorSet.DispObj(unionROI, hWindowControl1.HalconWindow);
                hWindowControl1.Refresh();
            }
        }
        private void ho_AdaptiveImage(int hv_ImageWidth, int hv_ImageHeight)
        {
            double rWindow = hWindowControl1.Width * 1.0f / hWindowControl1.Height;
            double rImage = hv_ImageWidth * 1.0f / hv_ImageHeight;
            if (rWindow > rImage)
            {
                double nw = (hv_ImageWidth * rWindow / rImage - hv_ImageWidth) / 2;
                double showWidth = nw + hv_ImageWidth;
                HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, nw * (-1), hv_ImageHeight, showWidth);
                scaleS_Y = 0;
                scaleS_X = nw * (-1);
                scaleE_Y = hv_ImageHeight;
                scaleE_X = showWidth;
            }
            else
            {
                double nh = (hWindowControl1.Height - hWindowControl1.Width / rImage) * hv_ImageHeight / hWindowControl1.Height;
                double showHeight = nh + hv_ImageHeight;
                HOperatorSet.SetPart(hWindowControl1.HalconWindow, nh * (-1), 0, showHeight, hv_ImageWidth);
                scaleS_Y = nh * (-1);
                scaleS_X = 0;
                scaleE_Y = showHeight;
                scaleE_X = hv_ImageWidth;
            }
        }
        private void 固定框放大ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (ho_Image != null)
            {
                HTuple hv_Row1 = null, hv_Column1 = null;
                HTuple hv_Row2 = null, hv_Column2 = null;
                hWindowControl1.Focus();
                isPaintShape = true;
                HOperatorSet.DrawRectangle1(hWindowControl1.HalconWindow, out hv_Row1, out hv_Column1, out hv_Row2, out hv_Column2);
                isPaintShape = false;
                double ratio = hv_ImageWidth.D / hv_ImageHeight.D;
                double rowLength = hv_Row2.D - hv_Row1.D;
                double colLength = hv_Column2.D - hv_Column1.D;
                if (rowLength <= 5 || colLength <= 5) return;
                if (rowLength < colLength)
                {
                    double newColLength = rowLength * ratio;
                    hv_Column2 = hv_Column1 + newColLength;
                }
                else
                {
                    double newRowLength = colLength / ratio;
                    hv_Row2 = hv_Row1 + newRowLength;
                }
                HOperatorSet.SetPart(hWindowControl1.HalconWindow, hv_Row1, hv_Column1, hv_Row2, hv_Column2);
                scaleS_Y = hv_Row1;
                scaleS_X = hv_Column1;
                scaleE_Y = hv_Row2;
                scaleE_X = hv_Column2;
                ShowDetectContour();
            }
        }
        private void 自适应图像ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (ho_Image != null)
            {
                ho_AdaptiveImage(hv_ImageWidth, hv_ImageHeight);
                ShowDetectContour();
            }
        }
        private void 加载图像ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "图片文件(*.jpg,*.tif,*.bmp,*.Png)|*.jpg;*.tif;*.bmp;*.Png";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                HOperatorSet.GenEmptyObj(out ho_Image);
                ho_Image.Dispose();
                HOperatorSet.ReadImage(out ho_Image, openFileDialog.FileName);    //加载图像
                HOperatorSet.GetImageSize(ho_Image, out hv_ImageWidth, out hv_ImageHeight);  //获取图像的宽和高
                HOperatorSet.CountChannels(ho_Image, out hv_Channel);
                this.lab_ImageInfo.Text = hv_ImageWidth.L.ToString() + "*" + hv_ImageHeight.L.ToString() + "*" + hv_Channel.L.ToString();
                int p = openFileDialog.FileName.LastIndexOf("\\");
                string imageName = openFileDialog.FileName.Substring(p + 1);
                this.lab_imageName.Text = imageName;     //图像名称
                ho_AdaptiveImage(hv_ImageWidth, hv_ImageHeight);
                ShowDetectContour();
            }
        }
        private void hWindowControl1_HMouseDown(object sender, HMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                mouseDownPoint.X = (int)e.X;
                mouseDownPoint.Y = (int)e.Y;
                mouseDownTime.Reset();  //右键获取点击的时间
                mouseDownTime.Start();
            }
        }
        private void hWindowControl1_HMouseMove(object sender, HMouseEventArgs e)
        {
            double scaleWidth = scaleE_X - scaleS_X;
            double scaleHeight = scaleE_Y - scaleS_Y;
            double coorX = (scaleWidth * e.X / hWindowControl1.ImagePart.Width) + scaleS_X;
            double coorY = (scaleHeight * e.Y / hWindowControl1.ImagePart.Height) + scaleS_Y;
            this.lab_Coor.Text = "Coor: " + coorX.ToString("f0") + "*" + coorY.ToString("f0");
            if (ho_Image != null && ho_Image.IsInitialized() && coorX > 0 && coorY > 0 && coorX < hv_ImageWidth && coorY < hv_ImageHeight)
            {
                HTuple hv_Grayval = new HTuple();
                HOperatorSet.GetGrayval(ho_Image, coorY, coorX, out hv_Grayval);
                if (hv_Channel == 3)
                {
                    if (hv_Grayval.Length > 0)
                    {
                        this.lab_GrayValue.Text = "Rgb: " + hv_Grayval[0].D.ToString("f0") + "*" + hv_Grayval[1].D.ToString("f0") + "*" + hv_Grayval[2].D.ToString("f0");
                    }
                }
                if (hv_Channel == 1)
                {
                    if (hv_Grayval.Length > 0)
                    {
                        this.lab_GrayValue.Text = "Rgb: " + hv_Grayval[0].D.ToString("f0");
                    }
                }
            }
            if (e.Button == MouseButtons.Right && ho_Image != null)
            {
                keyNum++;
                if (keyNum > 100000) keyNum = 0; //防止一直增加
                if (keyNum % 8 == 0)     //降低触发的频率
                {
                    double ratio_X = scaleWidth / hWindowControl1.ImagePart.Width;
                    double ratio_Y = scaleHeight / hWindowControl1.ImagePart.Height;
                    int moveX, moveY;   //X方向，Y方向移动大小。
                    hWindowControl1.Cursor = Cursors.SizeAll;
                    moveX = (int)e.X - mouseDownPoint.X;
                    moveY = (int)e.Y - mouseDownPoint.Y;
                    scaleS_Y = scaleS_Y - moveY * ratio_Y;
                    scaleS_X = scaleS_X - moveX * ratio_X;
                    scaleE_Y = scaleE_Y - moveY * ratio_Y;
                    scaleE_X = scaleE_X - moveX * ratio_X;
                    if (scaleE_X - scaleS_X < 10 || scaleE_Y - scaleS_Y < 10) return;
                    HOperatorSet.SetPart(hWindowControl1.HalconWindow, scaleS_Y, scaleS_X, scaleE_Y, scaleE_X);
                    ShowDetectContour();
                    mouseDownPoint.X = (int)e.X;
                    mouseDownPoint.Y = (int)e.Y;
                }
            }
        }
        private void hWindowControl1_HMouseUp(object sender, HMouseEventArgs e)
        {

        }
        private void hWindowControl1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                mouseDownTime.Stop();
                if (mouseDownTime.ElapsedMilliseconds < 200 && !isPaintShape)
                {
                    this.contextMenuStrip1.Show(this.hWindowControl1, new Point((int)e.X, (int)e.Y));
                }
            }
        }
        private void hWindowControl1_HMouseWheel(object sender, HMouseEventArgs e)
        {
            if (ho_Image != null && hv_ImageWidth != null)
            {
                wheelNum++;
                if (wheelNum > 10000) wheelNum = 0;
                if (wheelNum % 4 == 0)
                {
                    hWindowControl1.Focus();
                    double ratio = (scaleE_Y - scaleS_Y) / (scaleE_X - scaleS_X);
                    double zoomRatio = hv_ImageWidth.D / 2000;
                    double tempS_X = scaleS_X + e.Delta * zoomRatio;
                    double tempS_Y = scaleS_Y + e.Delta * zoomRatio * ratio;
                    double tempE_X = scaleE_X - e.Delta * zoomRatio;
                    double tempE_Y = scaleE_Y - e.Delta * zoomRatio * ratio;
                    if (tempE_X - tempS_X < 10 || tempE_Y - tempS_Y < 10)
                        return;
                    else
                    {
                        scaleS_X = tempS_X;
                        scaleS_Y = tempS_Y;
                        scaleE_X = tempE_X;
                        scaleE_Y = tempE_Y;
                    }
                    HOperatorSet.SetPart(hWindowControl1.HalconWindow, scaleS_Y, scaleS_X, scaleE_Y, scaleE_X);
                    ShowDetectContour();
                }
            }
        }
        #endregion
        private void btn_loadImage_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "图片文件(*.jpg,*.tif,*.bmp,*.Png)|*.jpg;*.tif;*.bmp;*.Png";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                HOperatorSet.GenEmptyObj(out ho_Image);
                ho_Image.Dispose();
                HOperatorSet.ReadImage(out ho_Image, openFileDialog.FileName);    //加载图像
                HOperatorSet.GetImageSize(ho_Image, out hv_ImageWidth, out hv_ImageHeight);  //获取图像的宽和高
                HOperatorSet.CountChannels(ho_Image, out hv_Channel);
                this.lab_ImageInfo.Text = hv_ImageWidth.L.ToString() + "*" + hv_ImageHeight.L.ToString() + "*" + hv_Channel.L.ToString();
                int p = openFileDialog.FileName.LastIndexOf("\\");
                string imageName = openFileDialog.FileName.Substring(p + 1);
                this.lab_imageName.Text = imageName;     //图像名称
                ho_AdaptiveImage(hv_ImageWidth, hv_ImageHeight);
                ShowDetectContour();
            }
        }

        private void btn_excuteCurItem_Click(object sender, EventArgs e)
        {
            if (ho_Image == null)
            {
                MessageBox.Show("请先加载图像！");
                return;
            }
            if (unionROI == null)
            {
                MessageBox.Show("请先绘制ROI！");
                return;
            }
            try
            {
                double limitMinRingWidth = double.Parse(this.tB_limitMinWidth.Text);
                double limitMaxRingWidth = double.Parse(this.tB_limitMaxWidth.Text);
                HTuple hv_cfgPara = new HTuple();
                hv_cfgPara[0] = (int)this.FitCircleMinGray.Value;
                hv_cfgPara[1] = (int)this.FitCircleMaxGray.Value;
                hv_cfgPara[2] = (int)this.FitCircle_contrast.Value;
                hv_cfgPara[3] = (int)this.FitCircle_pnum.Value;
                hv_cfgPara[4] = (int)this.FitCircle_sigma.Value;
                hv_cfgPara[5] = this.cB_FitCircle_seekPath.SelectedIndex;
                HTuple hv_ringWidth = null;
                HTuple hv_edgeRow1 = null, hv_edgeCol1 = null, hv_edgeRow2 = null;
                HTuple hv_edgeCol2 = null;
                //if (ho_fitCircleContour == null) 
                    HOperatorSet.GenEmptyObj(out ho_fitCircleContour);                
                //ho_fitCircleContour.Dispose();
                detectTime.Reset();
                detectTime.Start();
                if (this.cB_inheritModel.Checked)
                {
                    //继承于模板
                    HTuple hv_matchModel = null;
                    HTuple hv_modelRow = new HTuple();
                    HTuple hv_modelCol = new HTuple();
                    HTuple hv_modelAngle = new HTuple();
                    HTuple hv_modelScore = new HTuple();
                    if (curMatchPara.modelMatchType == 0)   //基于形状
                    {
                        string shapeModelFile = modelImageFold + "\\model.shm";
                        if (!File.Exists(shapeModelFile))
                        {
                            MessageBox.Show("模板文件不存在，请先加载模型！");
                            return;
                        }
                        HOperatorSet.ReadShapeModel(shapeModelFile, out hv_matchModel);  //加载模板
                        HOperatorSet.FindShapeModel(ho_Image, hv_matchModel, (new HTuple(curMatchPara.seekAngleStart)).TupleRad(), (new HTuple(curMatchPara.seekAngleRange)).TupleRad(), curMatchPara.seekModelScore * 0.01,
                           curMatchPara.seekModelNum, 0.5, "least_squares", 0, 0.9, out hv_modelRow, out hv_modelCol, out hv_modelAngle, out hv_modelScore); //查找模板 
                        HOperatorSet.ClearShapeModel(hv_matchModel);                     //清除模板
                    }
                    else if (curMatchPara.modelMatchType == 1)  //基于灰度
                    {
                        string nccModelFile = modelImageFold + "\\model.ncm";
                        if (!File.Exists(nccModelFile))
                        {
                            MessageBox.Show("模板文件不存在，请先加载模型！");
                            return;
                        }
                        HOperatorSet.ReadNccModel(nccModelFile, out hv_matchModel);  //加载模板
                        HOperatorSet.FindNccModel(ho_Image, hv_matchModel, (new HTuple(curMatchPara.seekAngleStart)).TupleRad(), (new HTuple(curMatchPara.seekAngleRange)).TupleRad(), curMatchPara.seekModelScore * 0.01, 
                            curMatchPara.seekModelNum, 0.5, "true", 0, out hv_modelRow, out hv_modelCol, out hv_modelAngle, out hv_modelScore);
                        HOperatorSet.ClearNccModel(hv_matchModel);                   //清除模板

                    }
                    if (hv_modelScore.Length != 1)
                    {
                        MessageBox.Show("模板定位失败！");
                        return;
                    }
                    HTuple hv_HomMat2D;
                    HOperatorSet.VectorAngleToRigid(curMatchPara.modelLocationRow, curMatchPara.modelLocationCol, 0, hv_modelRow[0],
                           hv_modelCol[0], hv_modelAngle[0], out hv_HomMat2D);   //根据模板坐标，求出放射矩阵
                    if (ho_AffinTransRegion == null) HOperatorSet.GenEmptyObj(out ho_AffinTransRegion);
                    ho_AffinTransRegion.Dispose();
                    HOperatorSet.AffineTransRegion(unionROI, out ho_AffinTransRegion, hv_HomMat2D, "nearest_neighbor");
                    halconAlgorithm.MeaCircleRingWidth(ho_Image, ho_AffinTransRegion, hv_cfgPara, out hv_ringWidth, out hv_edgeRow1, out hv_edgeCol1, out hv_edgeRow2, out hv_edgeCol2);
                }
                else
                {
                    halconAlgorithm.MeaCircleRingWidth(ho_Image, unionROI, hv_cfgPara, out hv_ringWidth, out hv_edgeRow1, out hv_edgeCol1, out hv_edgeRow2, out hv_edgeCol2);
                }
                detectTime.Stop();
                this.dataGridView1.Rows.Clear();
                bool isNG = false;
                for (int i = 0; i < hv_ringWidth.Length; i++)
                {
                    this.dataGridView1.Rows.Add();
                    this.dataGridView1.Rows[i].Cells[0].Value = i + 1;
                    this.dataGridView1.Rows[i].Cells[1].Value = hv_ringWidth.DArr[i].ToString("f2");
                    this.dataGridView1.Rows[i].Cells[2].Value = hv_edgeRow1.DArr[i].ToString("f2");
                    this.dataGridView1.Rows[i].Cells[3].Value = hv_edgeCol1.DArr[i].ToString("f2");
                    this.dataGridView1.Rows[i].Cells[4].Value = hv_edgeRow2.DArr[i].ToString("f2");
                    this.dataGridView1.Rows[i].Cells[5].Value = hv_edgeCol2.DArr[i].ToString("f2");
                    if(hv_ringWidth.DArr[i] < limitMinRingWidth || hv_ringWidth.DArr[i] > limitMaxRingWidth)
                    {
                        this.dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.Red;
                        HObject RegionLines = null;
                        HOperatorSet.GenEmptyObj(out RegionLines);
                        RegionLines.Dispose();
                        HOperatorSet.GenRegionLine(out RegionLines, hv_edgeRow1.DArr[i], hv_edgeCol1.DArr[i], hv_edgeRow2.DArr[i], hv_edgeCol2.DArr[i]);
                        HOperatorSet.Union2(ho_fitCircleContour, RegionLines, out ho_fitCircleContour);
                        RegionLines.Dispose();
                        isNG = true;
                    }
                }
                string detectResultShow = "检测结果：";
                if (isNG)
                    detectResultShow = detectResultShow + "NG，";
                else
                    detectResultShow = detectResultShow + "OK，";                
                ShowDetectContour();
                this.lab_executeState.Text = detectResultShow + "用时：" + detectTime.ElapsedMilliseconds.ToString() + "ms";
            }
            catch(Exception ex)
            {
                MessageBox.Show("检测失败！" + ex.Message);
            }
        }

        private void btn_quit_Click(object sender, EventArgs e)
        {
            if (ho_Image != null) ho_Image.Dispose();
            if (ho_fitCircleContour != null) ho_fitCircleContour.Dispose();
            if (unionROI != null) unionROI.Dispose();
            GC.Collect();
            this.Close();
        }

        private void btn_savePara_Click(object sender, EventArgs e)
        {
            try
            {
                if (unionROI == null)
                {
                    MessageBox.Show("请先绘制ROI！");
                    return;
                }
                outFitCirclePara.ho_ROI = unionROI.Clone();
                outFitCirclePara.minGray = (int)this.FitCircleMinGray.Value;
                outFitCirclePara.maxGray = (int)this.FitCircleMaxGray.Value;
                outFitCirclePara.contrast = (int)this.FitCircle_contrast.Value;
                outFitCirclePara.fitNum = (int)this.FitCircle_pnum.Value;
                outFitCirclePara.sigma = (int)this.FitCircle_sigma.Value;
                outFitCirclePara.seekPointPath = this.cB_FitCircle_seekPath.SelectedIndex;
                outFitCirclePara.limitMinRingWidth = double.Parse(this.tB_limitMinWidth.Text);
                outFitCirclePara.limitMaxRingWidth = double.Parse(this.tB_limitMaxWidth.Text);
                if (this.cB_inheritModel.Checked)
                    outFitCirclePara.isInheritModel = true;
                else
                    outFitCirclePara.isInheritModel = false;
            }
            catch(Exception ex)
            {
                MessageBox.Show("保存图像失败！" + ex.Message);
            }

        }

        private void btn_loadModelImage_Click(object sender, EventArgs e)
        {
            //加载模板图
            string modelImagePath = modelImageFold + "\\image.bmp";
            if (File.Exists(modelImagePath))
            {
                if (ho_Image == null) HOperatorSet.GenEmptyObj(out ho_Image);
                ho_Image.Dispose();
                HOperatorSet.ReadImage(out ho_Image, modelImagePath);    //加载图像
                HOperatorSet.GetImageSize(ho_Image, out hv_ImageWidth, out hv_ImageHeight);  //获取图像的宽和高
                HOperatorSet.CountChannels(ho_Image, out hv_Channel);
                this.lab_ImageInfo.Text = hv_ImageWidth.L.ToString() + "*" + hv_ImageHeight.L.ToString() + "*" + hv_Channel.L.ToString();
                this.lab_imageName.Text = "image.bmp";     //图像名称
                ho_AdaptiveImage(hv_ImageWidth, hv_ImageHeight);
                ShowDetectContour();
                //hWindowControl1.HalconWindow.ClearWindow();
                //HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);

            }
            else
            {
                MessageBox.Show("加载失败，模板图像不存在！");
            }
        }

        private void btn_drawCircleValue_Click(object sender, EventArgs e)
        {
            if (this.DrawCircle_X.Value > 0 && this.DrawCircle_Y.Value > 0 && this.DrawCircle_radius.Value > 0)
            {
                hWindowControl1.Focus();
                HTuple hv_Row = null, hv_Column = null, hv_Radius = null;
                HObject ho_Circle;
                HOperatorSet.GenEmptyObj(out ho_Circle);
                ho_Circle.Dispose();
                hv_Row = (int)this.DrawCircle_Y.Value;
                hv_Column = (int)this.DrawCircle_X.Value;
                hv_Radius = (int)this.DrawCircle_radius.Value;
                HOperatorSet.GenCircle(out ho_Circle, hv_Row, hv_Column, hv_Radius);
                switch (this.cB_RoiRelation.SelectedIndex)
                {
                    case 0:
                        if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                        HOperatorSet.Union2(ho_Circle, unionROI, out unionROI);
                        ShowDetectContour();
                        break;
                    case 1:
                        if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                        HOperatorSet.Intersection(unionROI, ho_Circle, out unionROI);
                        ShowDetectContour();
                        break;
                    case 2:
                        if (unionROI == null) HOperatorSet.GenEmptyObj(out unionROI);
                        HOperatorSet.Difference(unionROI, ho_Circle, out unionROI);
                        ShowDetectContour();
                        break;
                }
                ho_Circle.Dispose();
            }
            else
                MessageBox.Show("设置的参数必须>0");

        }
    }
}
